﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.InfoCardOfflineChainTrustValidator
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace Microsoft.InfoCards
{
  internal class InfoCardOfflineChainTrustValidator : X509CertificateValidator
  {
    private bool m_useMachineContext;

    public InfoCardOfflineChainTrustValidator(bool useMachineContext)
    {
      this.m_useMachineContext = useMachineContext;
    }

    public override void Validate(X509Certificate2 certificate)
    {
      X509Chain chain;
      this.Validate(certificate, (X509Certificate2Collection) null, out chain);
      chain = (X509Chain) null;
    }

    public void Validate(
      X509Certificate2 certificate,
      X509Certificate2Collection supportingCerts,
      out X509Chain chain)
    {
      if (certificate == null)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (certificate));
      chain = new X509Chain(this.m_useMachineContext);
      if (supportingCerts != null)
        chain.ChainPolicy.ExtraStore.AddRange(supportingCerts);
      chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
      chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
      chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreEndRevocationUnknown | X509VerificationFlags.IgnoreCtlSignerRevocationUnknown | X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown | X509VerificationFlags.IgnoreRootRevocationUnknown;
      if (!chain.Build(certificate))
        throw InfoCardTrace.ThrowHelperError((Exception) new SecurityTokenValidationException(SR.GetString("X509ChainBuildFail", (object) InfoCardOfflineChainTrustValidator.GetCertificateId(certificate), (object) InfoCardOfflineChainTrustValidator.GetChainStatusInformation(chain.ChainStatus))));
    }

    internal static string GetCertificateId(X509Certificate2 certificate)
    {
      StringBuilder str = new StringBuilder(256);
      InfoCardOfflineChainTrustValidator.AppendCertificateIdentityName(str, certificate);
      return str.ToString();
    }

    private static string GetChainStatusInformation(X509ChainStatus[] chainStatus)
    {
      if (chainStatus == null)
        return string.Empty;
      StringBuilder stringBuilder = new StringBuilder(256);
      for (int index = 0; index < chainStatus.Length; ++index)
      {
        if (X509ChainStatusFlags.RevocationStatusUnknown != chainStatus[index].Status && X509ChainStatusFlags.OfflineRevocation != chainStatus[index].Status)
        {
          stringBuilder.Append(chainStatus[index].StatusInformation);
          stringBuilder.Append(" ");
        }
      }
      return stringBuilder.ToString();
    }

    private static void AppendCertificateIdentityName(
      StringBuilder str,
      X509Certificate2 certificate)
    {
      string str1 = certificate.SubjectName.Name;
      if (string.IsNullOrEmpty(str1))
      {
        str1 = certificate.GetNameInfo(X509NameType.DnsName, false);
        if (string.IsNullOrEmpty(str1))
        {
          str1 = certificate.GetNameInfo(X509NameType.SimpleName, false);
          if (string.IsNullOrEmpty(str1))
          {
            str1 = certificate.GetNameInfo(X509NameType.EmailName, false);
            if (string.IsNullOrEmpty(str1))
              str1 = certificate.GetNameInfo(X509NameType.UpnName, false);
          }
        }
      }
      str.Append(string.IsNullOrEmpty(str1) ? "<x509>" : str1);
      str.Append("; ");
      str.Append(certificate.Thumbprint);
    }
  }
}
